
import java.util.ArrayList;
import java.util.List;

public class OneR {

	List<NurseryDTO> data;

	public enum ATTRIBUTE {
		PARENT(1, 2, 3), HAS_NURS(1, 2, 3, 4, 5), FORM(1, 2, 3, 4), 
		CHILDREN(1,	2, 3, 4), HOUSING(1, 2, 3), FINANCE(1, 2), SOCIAL(1, 2, 3), 
		HEALTH(1, 2, 3), CLASSIFICATION(1, 2, 3, 4, 5);
		private int x[];

		ATTRIBUTE(int... x) {
			this.x = x;
		}

		public int[] getValues() {
			return x;
		}
	};

	public OneR(List<NurseryDTO> nurseryDTOS) {
		data = nurseryDTOS;
	}

	public void eval() {
		double minError = Double.MAX_VALUE;
		ATTRIBUTE result = null;
		double error;
		System.out.println("**********ERRORS*************");
		for (ATTRIBUTE attribute : ATTRIBUTE.values()) {

			error = calculateAttributeError(attribute);
			if (error < minError) {
				minError = error;
				result = attribute;

			}
			if(attribute.name().equals("CLASSIFICATION")) break;
			System.out.println(attribute + " : " + error);
		}
		System.out.println("**********RESULTS*************");
		System.out.println(result + " : ");
		System.out.println("Error: " + minError);
	}

	public final double calculateAttributeError(final ATTRIBUTE attribute) {
		double totalError = 0;
		int totalInstances = 0;
		int mostOccuringClassifications = 0;
		for (int value : attribute.getValues()) {

			List<NurseryDTO> result = gatherNurseryDTO(attribute, value);
			int bucket[] = new int[5];
			for (NurseryDTO dto : result) {
				bucket[dto.getClassification() - 1]++;
			}

			int maxValue = Integer.MIN_VALUE;
			for (int x : bucket) {
				if (x > maxValue) {
					maxValue = x;
				}
				totalInstances += x;
			}
			mostOccuringClassifications += maxValue;

		}
		totalError = (double)(mostOccuringClassifications) / (double)totalInstances;
		return totalError;
	}

	public final List<NurseryDTO> gatherNurseryDTO(final ATTRIBUTE attribute,
			final int value) {
		List<NurseryDTO> result = new ArrayList<NurseryDTO>();
		for (NurseryDTO dto : data) {
			switch (attribute) {
			case PARENT:
				if (dto.getParents() == value) {
					result.add(dto);
				}
				break;
			case HAS_NURS:
				if (dto.getHas_nurs() == value) {
					result.add(dto);
				}
				break;
			case FORM:
				if (dto.getForm() == value) {
					result.add(dto);
				}
				break;
			case CHILDREN:
				if (dto.getChildren() == value) {
					result.add(dto);
				}
				break;
			case HOUSING:
				if (dto.getHousing() == value) {
					result.add(dto);
				}
				break;
			case FINANCE:
				if (dto.getFinance() == value) {
					result.add(dto);
				}
				break;
			case SOCIAL:
				if (dto.getSocial() == value) {
					result.add(dto);
				}
				break;
			case HEALTH:
				if (dto.getHealth() == value) {
					result.add(dto);
				}
				break;
			default:
				break;
			}
		}
		return result;
	}

}
